#include "rule.hpp"
#include "../utils/utils.hpp"

namespace mashine { namespace kb {

using namespace std;

Rule::Rule() : Entity<Literal>("<empty>", new vector<Literal *>())
{
	APP_LOGGER(info) << "Rule {" << toString() << "} instantiated";
}

Rule::Rule(vector<Literal *> * literals, string name) : Entity<Literal>(name, literals)
{
//	APP_LOGGER(info) << "literals address=" << literals << " size=" << literals->size() << "values=" << utils::vector_to_string<Literal>(*literals);
	
	for (vector<Literal *>::const_iterator i = literals->begin(); i != literals->end(); ++i)
    {
//		APP_LOGGER(info) << "Disjunct {" << (*i)->toString() << "} instantiated";
		
		if (!(*i)->isDenied())
		{
			undeniable = (this->undeniable == NULL) ? *i : NULL;
		} 
    }
	
	APP_LOGGER(info) << "Rule {" << toString() << "} instantiated";
}

Rule::~Rule()
{
	delete undeniable;
	APP_LOGGER(info) << "Rule {" << toString() << "} begins to break down";
}

string Rule::toString() const
{
	if (undeniable == NULL)
	{
		return "<empty>";
	}
	
	string res;

	//res.append(undeniable->toString());
	//res.append("<-");
	
	vector<Literal *>::const_iterator i;
    for (i = params->begin(); i != params->end(); i++)
    {
        res += (*i)->toString();
        res += "; ";
    }
	
	if (params->size() != 2) 
	{
		res.erase(res.size() - 2, 2);
    }
	
	return res;
}

/**
 * return string representation object
 */
Literal const * Rule::getUndeniableLiteral() const
{	
	return undeniable;
}

/**
 * set undeniable literal
 */	
void Rule::setUndeniableLiteral(Literal * undeniable)
{
	this->undeniable = undeniable;
}

/**
 * need owerride this method in child class 
 * to correct work Entity constructor
 */
bool Rule::validateName(std::string & name) const
{
	APP_LOGGER(info) << "Literal {" << toString() << "} params validating begin";

	return true;
}

/**
 * need owerride this method in child class 
 * to correct work Entity constructor
 */
bool Rule::validateParam(std::vector<Literal *> * params) const
{
	APP_LOGGER(info) << "Literal {" << toString() << "} params validating begin";

	//TODO: add more details validation
	
	return true;
}

}}